suppressPackageStartupMessages(library(tidyverse))
library(gapminder)

Saving Graphs to File

p <- ggplot(mtcars, aes(hp, wt)) + 
    geom_point()
ggsave("my_plot.png", p)
Saving 7 x 7 in image

Scales; Colour

Scale functions in ggplot2 take the form scale_[aesthetic]_[mapping]().

Let’s first focus on the following plot:

p_scales <- ggplot(gapminder, aes(gdpPercap, lifeExp)) +
     geom_point(aes(colour=pop), alpha=0.2)
p_scales + 
    scale_x_log10() +
    scale_colour_continuous(trans="log10")

  1. Change the y-axis tick mark spacing to 10; change the colour spacing to include all powers of 10.
p_scales +
    scale_x_log10() +
    scale_colour_continuous(
        trans  = "log10", 
        breaks = 10^(1:10)
    ) +
    scale_y_continuous(breaks=1:10 * 10)

  1. Specify scales::*_format in the labels argument of a scale function to do the following:
    • Change the x-axis labels to dollar format (use scales::dollar_format())
    • Change the colour labels to comma format (use scales::comma_format())
library(scales)

Attaching package: 㤼㸱scales㤼㸲

The following object is masked from 㤼㸱package:purrr㤼㸲:

    discard

The following object is masked from 㤼㸱package:readr㤼㸲:

    col_factor
p_scales +
    scale_x_log10(labels=dollar_format()) +
    scale_colour_continuous(
        trans  = "log10", 
        breaks = 10^(1:10),
        labels = comma_format()
    ) +
    scale_y_continuous(breaks=10*(1:10))

  1. Use RColorBrewer to change the colour scheme.
    • Notice the three different types of scales: sequential, diverging, and continuous.
## All palettes the come with RColorBrewer:
RColorBrewer::display.brewer.all()

p_scales +
    scale_x_log10(labels=dollar_format()) +
    scale_color_distiller(
        trans   = "log10",
        breaks  = 10^(1:10),
        labels  = comma_format(),
        palette = "Greens"
    ) +
    scale_y_continuous(breaks=10*(1:10))

  1. Use viridis to change the colour to a colour-blind friendly scheme
    • Hint: add scale_colour_viridis_c (c stands for continuous; d discrete).
    • You can choose a palette with option.
p_scales +
    scale_x_log10(labels=dollar_format()) +
    scale_color_viridis_c(
        trans   = "log10",
        breaks  = 10^(1:10),
        labels  = comma_format(),
    ) +
    scale_y_continuous(breaks=10*(1:10))

Theming

Changing the look of a graphic can be achieved through the theme() layer.

There are “complete themes” that come with ggplot2, my favourite being theme_bw (I’ve grown tired of the default gray background, so theme_bw is refreshing).

  1. Change the theme of the following plot to theme_bw():
ggplot(iris, aes(Sepal.Width, Sepal.Length)) +
     facet_wrap(~ Species) +
     geom_point() +
     labs(x = "Sepal Width",
          y = "Sepal Length",
          title = "Sepal sizes of three plant species") +
  theme_bw()

  1. Then, change font size of axis labels, and the strip background colour. Others?
ggplot(iris, aes(Sepal.Width, Sepal.Length)) +
     facet_wrap(~ Species) +
     geom_point() +
     labs(x = "Sepal Width",
          y = "Sepal Length",
          title = "Sepal sizes of three plant species") +
    theme_bw() +
    theme(axis.text = element_text(size = 16),
          strip.background = element_rect(fill = "orange"),
          panel.background = element_rect(fill = "blue"))

Plotly

Consider the following plot:

(p <- gapminder %>% 
     filter(continent != "Oceania") %>% 
     ggplot(aes(gdpPercap, lifeExp)) +
     geom_point(aes(colour=pop), alpha=0.2) +
     scale_x_log10(labels=dollar_format()) +
     scale_colour_distiller(
         trans   = "log10",
         breaks  = 10^(1:10),
         labels  = comma_format(),
         palette = "Greens"
     ) +
     facet_wrap(~ continent) +
     scale_y_continuous(breaks=10*(1:10)) +
     theme_bw())

  1. Convert it to a plotly object by applying the ggplotly() function:
library(plotly)

Attaching package: 㤼㸱plotly㤼㸲

The following object is masked from 㤼㸱package:ggplot2㤼㸲:

    last_plot

The following object is masked from 㤼㸱package:stats㤼㸲:

    filter

The following object is masked from 㤼㸱package:graphics㤼㸲:

    layout
ggplotly(p)
  1. You can save a plotly graph locally as an html file. Try saving the above:
    • NOTE: plotly graphs don’t seem to show up in Rmd notebooks, but they do with Rmd documents.
p %>% 
    ggplotly() %>% 
    htmlwidgets::saveWidget("LOCATION_GOES_HERE")
  1. Run this code to see the json format underneath:
p %>% 
    ggplotly() %>% 
    plotly_json()
Error: Package `listviewer` required for `plotly_json`.
Please install and try again.
  1. Check out code to make a plotly object from scratch using plot_ly() – scatterplot of gdpPercap vs lifeExp.
plot_ly(gapminder, 
        x = ~gdpPercap, 
        y = ~lifeExp, 
        type = "scatter",
        mode = "markers",
        opacity = 0.2) %>% 
    layout(xaxis = list(type = "log"))
  1. Add population to form a z-axis for a 3D plot:
plot_ly(gapminder, 
        x = ~gdpPercap, 
        y = ~lifeExp, 
        z = ~pop,
        type = "scatter3d",
        mode = "markers",
        opacity = 0.2)
LS0tDQp0aXRsZTogImNtMDEzIEV4ZXJjaXNlIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUNCi0tLQ0KDQpgYGB7cn0NCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KHRpZHl2ZXJzZSkpDQpsaWJyYXJ5KGdhcG1pbmRlcikNCmBgYA0KDQoNCiMgU2F2aW5nIEdyYXBocyB0byBGaWxlDQoNCi0gRG9uJ3QgdXNlIHRoZSBtb3VzZQ0KLSBVc2UgYGdnc2F2ZWAgZm9yIGdncGxvdA0KICAgIC0gUHJhY3RpY2UgYnkgc2F2aW5nIHRoZSBmb2xsb3dpbmcgcGxvdCB0byBmaWxlOiANCg0KYGBge3J9DQpwIDwtIGdncGxvdChtdGNhcnMsIGFlcyhocCwgd3QpKSArIA0KICAgIGdlb21fcG9pbnQoKQ0KZ2dzYXZlKCJteV9wbG90LnBuZyIsIHApDQpgYGANCg0KLSBCYXNlIFIgd2F5OiBwcmludCBwbG90cyAidG8gc2NyZWVuIiwgc2FuZHdpY2hlZCBiZXR3ZWVuIGBwZGYoKWAvYGpwZWcoKWAvYHBuZygpYC4uLiBhbmQgYGRldi5vZmYoKWAuIA0KLSBWZWN0b3IgdnMuIHJhc3RlcjogSW1hZ2VzIGFyZSBzdG9yZWQgb24geW91ciBjb21wdXRlciBhcyBlaXRoZXIgX3ZlY3Rvcl8gb3IgX3Jhc3Rlcl8uDQogICAgLSBfX1Jhc3Rlcl9fOiBhbiBgbmAgYnkgYG1gIGdyaWQgb2YgcGl4ZWxzLCBlYWNoIHdpdGggaXRzIG93biBjb2xvdXIuIGBqcGVnYCwgYHBuZ2AsIGBnaWZgLCBgYm1wYC4NCiAgICAtIF9fVmVjdG9yX186IHJlcHJlc2VudGVkIGFzIHNoYXBlcyBhbmQgbGluZXMuIGBwZGZgLCBbYHN2Z2BdKGh0dHBzOi8vd3d3Lnczc2Nob29scy5jb20vZ3JhcGhpY3Mvc3ZnX2ludHJvLmFzcCkuDQogICAgLSBGb3IgdGlwczogWyIxMCB0aXBzIGZvciBtYWtpbmcgeW91ciBSIGdyYXBoaWNzIGxvb2sgdGhlaXIgYmVzdCIiXShodHRwOi8vYmxvZy5yZXZvbHV0aW9uYW5hbHl0aWNzLmNvbS8yMDA5LzAxLzEwLXRpcHMtZm9yLW1ha2luZy15b3VyLXItZ3JhcGhpY3MtbG9vay10aGVpci1iZXN0Lmh0bWwpLg0KICAgIA0KIyBTY2FsZXM7IENvbG91cg0KDQpTY2FsZSBmdW5jdGlvbnMgaW4gYGdncGxvdDJgIHRha2UgdGhlIGZvcm0gYHNjYWxlX1thZXN0aGV0aWNdX1ttYXBwaW5nXSgpYC4NCg0KTGV0J3MgZmlyc3QgZm9jdXMgb24gdGhlIGZvbGxvd2luZyBwbG90Og0KDQpgYGB7cn0NCnBfc2NhbGVzIDwtIGdncGxvdChnYXBtaW5kZXIsIGFlcyhnZHBQZXJjYXAsIGxpZmVFeHApKSArDQogICAgIGdlb21fcG9pbnQoYWVzKGNvbG91cj1wb3ApLCBhbHBoYT0wLjIpDQpwX3NjYWxlcyArIA0KICAgIHNjYWxlX3hfbG9nMTAoKSArDQogICAgc2NhbGVfY29sb3VyX2NvbnRpbnVvdXModHJhbnM9ImxvZzEwIikNCmBgYA0KDQoxLiBDaGFuZ2UgdGhlIHktYXhpcyB0aWNrIG1hcmsgc3BhY2luZyB0byAxMDsgY2hhbmdlIHRoZSBjb2xvdXIgc3BhY2luZyB0byBpbmNsdWRlIGFsbCBwb3dlcnMgb2YgMTAuDQoNCmBgYHtyfQ0KcF9zY2FsZXMgKw0KICAgIHNjYWxlX3hfbG9nMTAoKSArDQogICAgc2NhbGVfY29sb3VyX2NvbnRpbnVvdXMoDQogICAgICAgIHRyYW5zICA9ICJsb2cxMCIsIA0KICAgICAgICBicmVha3MgPSAxMF4oMToxMCkNCiAgICApICsNCiAgICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPTE6MTAgKiAxMCkNCmBgYA0KDQoyLiBTcGVjaWZ5IGBzY2FsZXM6OipfZm9ybWF0YCBpbiB0aGUgYGxhYmVsc2AgYXJndW1lbnQgb2YgYSBzY2FsZSBmdW5jdGlvbiB0byBkbyB0aGUgZm9sbG93aW5nOg0KICAgIC0gQ2hhbmdlIHRoZSB4LWF4aXMgbGFiZWxzIHRvIGRvbGxhciBmb3JtYXQgKHVzZSBgc2NhbGVzOjpkb2xsYXJfZm9ybWF0KClgKQ0KICAgIC0gQ2hhbmdlIHRoZSBjb2xvdXIgbGFiZWxzIHRvIGNvbW1hIGZvcm1hdCAodXNlIGBzY2FsZXM6OmNvbW1hX2Zvcm1hdCgpYCkNCg0KYGBge3J9DQpsaWJyYXJ5KHNjYWxlcykNCnBfc2NhbGVzICsNCiAgICBzY2FsZV94X2xvZzEwKGxhYmVscz1kb2xsYXJfZm9ybWF0KCkpICsNCiAgICBzY2FsZV9jb2xvdXJfY29udGludW91cygNCiAgICAgICAgdHJhbnMgID0gImxvZzEwIiwgDQogICAgICAgIGJyZWFrcyA9IDEwXigxOjEwKSwNCiAgICAgICAgbGFiZWxzID0gY29tbWFfZm9ybWF0KCkNCiAgICApICsNCiAgICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPTEwKigxOjEwKSkNCmBgYA0KDQozLiBVc2UgYFJDb2xvckJyZXdlcmAgdG8gY2hhbmdlIHRoZSBjb2xvdXIgc2NoZW1lLg0KICAgIC0gTm90aWNlIHRoZSB0aHJlZSBkaWZmZXJlbnQgdHlwZXMgb2Ygc2NhbGVzOiBzZXF1ZW50aWFsLCBkaXZlcmdpbmcsIGFuZCBjb250aW51b3VzLg0KDQpgYGB7cn0NCiMjIEFsbCBwYWxldHRlcyB0aGUgY29tZSB3aXRoIFJDb2xvckJyZXdlcjoNClJDb2xvckJyZXdlcjo6ZGlzcGxheS5icmV3ZXIuYWxsKCkNCnBfc2NhbGVzICsNCiAgICBzY2FsZV94X2xvZzEwKGxhYmVscz1kb2xsYXJfZm9ybWF0KCkpICsNCiAgICBzY2FsZV9jb2xvcl9kaXN0aWxsZXIoDQogICAgICAgIHRyYW5zICAgPSAibG9nMTAiLA0KICAgICAgICBicmVha3MgID0gMTBeKDE6MTApLA0KICAgICAgICBsYWJlbHMgID0gY29tbWFfZm9ybWF0KCksDQogICAgICAgIHBhbGV0dGUgPSAiR3JlZW5zIg0KICAgICkgKw0KICAgIHNjYWxlX3lfY29udGludW91cyhicmVha3M9MTAqKDE6MTApKQ0KYGBgDQoNCjQuIFVzZSBgdmlyaWRpc2AgdG8gY2hhbmdlIHRoZSBjb2xvdXIgdG8gYSBjb2xvdXItYmxpbmQgZnJpZW5kbHkgc2NoZW1lDQogICAgLSBIaW50OiBhZGQgYHNjYWxlX2NvbG91cl92aXJpZGlzX2NgIChgY2Agc3RhbmRzIGZvciBjb250aW51b3VzOyBgZGAgZGlzY3JldGUpLg0KICAgIC0gWW91IGNhbiBjaG9vc2UgYSBwYWxldHRlIHdpdGggYG9wdGlvbmAuDQoNCmBgYHtyfQ0KcF9zY2FsZXMgKw0KICAgIHNjYWxlX3hfbG9nMTAobGFiZWxzPWRvbGxhcl9mb3JtYXQoKSkgKw0KICAgIHNjYWxlX2NvbG9yX3ZpcmlkaXNfYygNCiAgICAgICAgdHJhbnMgICA9ICJsb2cxMCIsDQogICAgICAgIGJyZWFrcyAgPSAxMF4oMToxMCksDQogICAgICAgIGxhYmVscyAgPSBjb21tYV9mb3JtYXQoKSwNCiAgICApICsNCiAgICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPTEwKigxOjEwKSkNCmBgYA0KDQojIFRoZW1pbmcNCg0KQ2hhbmdpbmcgdGhlIGxvb2sgb2YgYSBncmFwaGljIGNhbiBiZSBhY2hpZXZlZCB0aHJvdWdoIHRoZSBgdGhlbWUoKWAgbGF5ZXIuDQoNClRoZXJlIGFyZSBbImNvbXBsZXRlIHRoZW1lcyJdKGh0dHA6Ly9nZ3Bsb3QyLnRpZHl2ZXJzZS5vcmcvcmVmZXJlbmNlL2dndGhlbWUuaHRtbCkgdGhhdCBjb21lIHdpdGggYGdncGxvdDJgLCBteSBmYXZvdXJpdGUgYmVpbmcgYHRoZW1lX2J3YCAoSSd2ZSBncm93biB0aXJlZCBvZiB0aGUgZGVmYXVsdCBncmF5IGJhY2tncm91bmQsIHNvIGB0aGVtZV9id2AgaXMgcmVmcmVzaGluZykuDQoNCjEuIENoYW5nZSB0aGUgdGhlbWUgb2YgdGhlIGZvbGxvd2luZyBwbG90IHRvIGB0aGVtZV9idygpYDoNCg0KYGBge3J9DQpnZ3Bsb3QoaXJpcywgYWVzKFNlcGFsLldpZHRoLCBTZXBhbC5MZW5ndGgpKSArDQogICAgIGZhY2V0X3dyYXAofiBTcGVjaWVzKSArDQogICAgIGdlb21fcG9pbnQoKSArDQogICAgIGxhYnMoeCA9ICJTZXBhbCBXaWR0aCIsDQogICAgICAgICAgeSA9ICJTZXBhbCBMZW5ndGgiLA0KICAgICAgICAgIHRpdGxlID0gIlNlcGFsIHNpemVzIG9mIHRocmVlIHBsYW50IHNwZWNpZXMiKSArDQogIHRoZW1lX2J3KCkNCmBgYA0KDQoyLiBUaGVuLCBjaGFuZ2UgZm9udCBzaXplIG9mIGF4aXMgbGFiZWxzLCBhbmQgdGhlIHN0cmlwIGJhY2tncm91bmQgY29sb3VyLiBPdGhlcnM/DQoNCmBgYHtyfQ0KZ2dwbG90KGlyaXMsIGFlcyhTZXBhbC5XaWR0aCwgU2VwYWwuTGVuZ3RoKSkgKw0KICAgICBmYWNldF93cmFwKH4gU3BlY2llcykgKw0KICAgICBnZW9tX3BvaW50KCkgKw0KICAgICBsYWJzKHggPSAiU2VwYWwgV2lkdGgiLA0KICAgICAgICAgIHkgPSAiU2VwYWwgTGVuZ3RoIiwNCiAgICAgICAgICB0aXRsZSA9ICJTZXBhbCBzaXplcyBvZiB0aHJlZSBwbGFudCBzcGVjaWVzIikgKw0KICAgIHRoZW1lX2J3KCkgKw0KICAgIHRoZW1lKGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTYpLA0KICAgICAgICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJvcmFuZ2UiKSwNCiAgICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiYmx1ZSIpKQ0KYGBgDQoNCg0KIyBQbG90bHkNCg0KQ29uc2lkZXIgdGhlIGZvbGxvd2luZyBwbG90Og0KDQpgYGB7cn0NCihwIDwtIGdhcG1pbmRlciAlPiUgDQogICAgIGZpbHRlcihjb250aW5lbnQgIT0gIk9jZWFuaWEiKSAlPiUgDQogICAgIGdncGxvdChhZXMoZ2RwUGVyY2FwLCBsaWZlRXhwKSkgKw0KICAgICBnZW9tX3BvaW50KGFlcyhjb2xvdXI9cG9wKSwgYWxwaGE9MC4yKSArDQogICAgIHNjYWxlX3hfbG9nMTAobGFiZWxzPWRvbGxhcl9mb3JtYXQoKSkgKw0KICAgICBzY2FsZV9jb2xvdXJfZGlzdGlsbGVyKA0KICAgICAgICAgdHJhbnMgICA9ICJsb2cxMCIsDQogICAgICAgICBicmVha3MgID0gMTBeKDE6MTApLA0KICAgICAgICAgbGFiZWxzICA9IGNvbW1hX2Zvcm1hdCgpLA0KICAgICAgICAgcGFsZXR0ZSA9ICJHcmVlbnMiDQogICAgICkgKw0KICAgICBmYWNldF93cmFwKH4gY29udGluZW50KSArDQogICAgIHNjYWxlX3lfY29udGludW91cyhicmVha3M9MTAqKDE6MTApKSArDQogICAgIHRoZW1lX2J3KCkpDQpgYGANCg0KMS4gQ29udmVydCBpdCB0byBhIGBwbG90bHlgIG9iamVjdCBieSBhcHBseWluZyB0aGUgYGdncGxvdGx5KClgIGZ1bmN0aW9uOg0KDQpgYGB7cn0NCmxpYnJhcnkocGxvdGx5KQ0KZ2dwbG90bHkocCkNCmBgYA0KDQoyLiBZb3UgY2FuIHNhdmUgYSBwbG90bHkgZ3JhcGggbG9jYWxseSBhcyBhbiBodG1sIGZpbGUuIFRyeSBzYXZpbmcgdGhlIGFib3ZlOg0KICAgIC0gTk9URTogcGxvdGx5IGdyYXBocyBkb24ndCBzZWVtIHRvIHNob3cgdXAgaW4gUm1kIF9ub3RlYm9va3NfLCBidXQgdGhleSBkbyB3aXRoIFJtZCBfZG9jdW1lbnRzXy4NCg0KYGBge3J9DQpwICU+JSANCiAgICBnZ3Bsb3RseSgpICU+JSANCiAgICBodG1sd2lkZ2V0czo6c2F2ZVdpZGdldCgiTE9DQVRJT05fR09FU19IRVJFIikNCmBgYA0KDQoNCjMuIFJ1biB0aGlzIGNvZGUgdG8gc2VlIHRoZSBqc29uIGZvcm1hdCB1bmRlcm5lYXRoOg0KDQpgYGB7cn0NCnAgJT4lIA0KICAgIGdncGxvdGx5KCkgJT4lIA0KICAgIHBsb3RseV9qc29uKCkNCmBgYA0KDQoNCjQuIENoZWNrIG91dCBjb2RlIHRvIG1ha2UgYSBwbG90bHkgb2JqZWN0IGZyb20gc2NyYXRjaCB1c2luZyBgcGxvdF9seSgpYCAtLSBzY2F0dGVycGxvdCBvZiBnZHBQZXJjYXAgdnMgbGlmZUV4cC4NCiAgICAtIENoZWNrIG91dCB0aGUgW2NoZWF0IHNoZWV0XShodHRwczovL2ltYWdlcy5wbG90Lmx5L3Bsb3RseS1kb2N1bWVudGF0aW9uL2ltYWdlcy9yX2NoZWF0X3NoZWV0LnBkZikuDQoNCmBgYHtyfQ0KcGxvdF9seShnYXBtaW5kZXIsIA0KICAgICAgICB4ID0gfmdkcFBlcmNhcCwgDQogICAgICAgIHkgPSB+bGlmZUV4cCwgDQogICAgICAgIHR5cGUgPSAic2NhdHRlciIsDQogICAgICAgIG1vZGUgPSAibWFya2VycyIsDQogICAgICAgIG9wYWNpdHkgPSAwLjIpICU+JSANCiAgICBsYXlvdXQoeGF4aXMgPSBsaXN0KHR5cGUgPSAibG9nIikpDQpgYGANCg0KNS4gQWRkIHBvcHVsYXRpb24gdG8gZm9ybSBhIHotYXhpcyBmb3IgYSAzRCBwbG90Og0KDQpgYGB7cn0NCnBsb3RfbHkoZ2FwbWluZGVyLCANCiAgICAgICAgeCA9IH5nZHBQZXJjYXAsIA0KICAgICAgICB5ID0gfmxpZmVFeHAsIA0KICAgICAgICB6ID0gfnBvcCwNCiAgICAgICAgdHlwZSA9ICJzY2F0dGVyM2QiLA0KICAgICAgICBtb2RlID0gIm1hcmtlcnMiLA0KICAgICAgICBvcGFjaXR5ID0gMC4yKQ0KYGBgDQoNCg0KDQo=